package com.server.questionbank.snframe.service.CourseService.Impl.Resource;

import com.server.questionbank.snframe.controller.Course.pojo.Resource.CreateCourseResource;
import com.server.questionbank.snframe.domain.Course.Resource.CourseFiles;
import com.server.questionbank.snframe.domain.Course.Resource.CourseResource;
import com.server.questionbank.snframe.domain.Course.Result.CourseResourceInfo;
import com.server.questionbank.snframe.domain.User.TUser;
import com.server.questionbank.snframe.mapper.Course.Resource.CourseFilesMapper;
import com.server.questionbank.snframe.mapper.Course.Resource.CourseResourcesMapper;
import com.server.questionbank.snframe.service.CourseService.Resource.CourseFileService;
import com.server.questionbank.snframe.service.CourseService.Resource.CourseResourceService;
import com.server.questionbank.snframe.service.UsersService.UsersService;
import com.server.questionbank.snframe.util.MinIo.MinIoBucket;
import com.server.questionbank.snframe.util.MinIo.MinIoFactory;
import com.server.questionbank.snframe.util.MinIo.ProgressInputStream;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CourseResourceServiceImpl implements CourseResourceService {
    @Autowired
    private CourseResourcesMapper courseResourcesMapper;
    @Autowired
    private CourseFileService courseFileService;
    @Autowired
    private UsersService usersService;
    @Autowired
    private MinIoFactory minIoFactory;
    @Autowired
    private StringRedisTemplate redisTemplate;

    // 获取课程资源列表
    @Override
    public List<CourseResourceInfo> getResourceList(Long courseId) {
        return courseResourcesMapper.getResourceList(courseId).stream()
                .map(resource -> {
                    // 创建子类对象并拷贝基础字段
                    CourseResourceInfo info = new CourseResourceInfo();
                    BeanUtils.copyProperties(resource, info); // 需要Spring-beans依赖

                    // 填充额外字段
                    try {
                        info.setFileCount((long) courseFileService.getFileListByResourceId(resource.getResourceId()).size());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    info.setUploadUser(usersService.selectUserById(resource.getUploadUserId()));

                    return info;
                }).collect(Collectors.toList());
    }

    // 获取资源信息
    @Override
    public CourseResourceInfo getResourceInfo(Long resourceId) throws Exception {
        CourseResource resource = courseResourcesMapper.getResourceInfo(resourceId);
        CourseResourceInfo info = new CourseResourceInfo(resource);
        info.setFileList(courseFileService.getFileListByResourceId(resource.getResourceId()));
        info.setUploadUser(usersService.selectUserById(info.getUploadUserId()));
        return info;
    }

    // 根据文件 ID 获取资源信息
    @Override
    public CourseResourceInfo getResourceInfoByFileId(Long fileId) throws Exception {
        CourseResource resource = courseResourcesMapper.getResourceInfoByFileId(fileId);
        CourseResourceInfo info = new CourseResourceInfo(resource);
        info.setFileList(courseFileService.getFileListByResourceId(resource.getResourceId()));
        info.setUploadUser(usersService.selectUserById(info.getUploadUserId()));
        return info;
    }

    // 创建课程资源
    @Override
    public Boolean createResource(CreateCourseResource createCourseResource, Long createBy) {
        return courseResourcesMapper.createResource(createCourseResource, createBy) > 0;
    }

    // 上传文件
    @Override
    public void uploadFlie(MultipartFile file, CourseResource courseResource) throws Exception {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("❌ 上传文件不能为空");
        }
        if (courseResource == null) {
            throw new IllegalArgumentException("❌ 上传文件信息不能为空");
        }

        MinIoBucket  minIoBucket = minIoFactory.openBucket("course");

        String contentType = file.getContentType();
        long size = file.getSize();

        // 创建文件
        CourseFiles courseFiles = new CourseFiles();
        courseFiles.setFileName(file.getOriginalFilename());
        courseFiles.setFileSize(size);
        courseFiles.setFilePath("");
        courseFiles.setResourceId(courseResource.getResourceId());
        if (!courseFileService.createFile(courseFiles)) throw new Exception("创建文件失败");
        courseFiles.setFilePath(courseResource.getCourseId() + "/resources/" + courseFiles.getResourceId() + "/" + courseFiles.getFileId() + "_" + courseFiles.getFileName());
        if (!courseFileService.updateFilePath(courseFiles.getFilePath(), courseFiles.getFileId())) throw new Exception("更新文件路径失败");
        // 上传文件
        try (InputStream inputStream = file.getInputStream()) {
            // 使用自定义的 ProgressInputStream 来计算进度
            ProgressInputStream.ProgressListener progressListener = progress -> {};

            try (ProgressInputStream progressInputStream = new ProgressInputStream(
                    inputStream, size, progressListener,
                    "upload_course_resource_" + courseFiles.getResourceId(), redisTemplate)) {
                minIoBucket.uploadFile(courseFiles.getFilePath(), progressInputStream, contentType, size);
            }
        }
    }

    @Override
    public InputStream downloadFile(String filePath, long start, long end) throws Exception {
        MinIoBucket minIoBucket = minIoFactory.openBucket("course");
        return minIoBucket.downloadFile(filePath, start, end);
    }
    @Override
    public InputStream downloadFile(String filePath) throws Exception {
        MinIoBucket minIoBucket = minIoFactory.openBucket("course");
        return minIoBucket.downloadFile(filePath);
    }
}
